<template>
  <div class="page-container">
    <div class="page-header-card">
      <div class="header-content">
        <div class="header-left">
          <el-button class="back-button" @click="goBack">
            <el-icon><Back /></el-icon>
            <span>返回</span>
          </el-button>
          <div class="page-title">{{ this.case !== null ? '编辑用例' : '新增用例' }}</div>
        </div>
        <div class="header-actions">
          <el-tooltip content="展开所有步骤" placement="top" :disabled="isExpand">
            <el-button v-if="!isExpand" class="action-button" @click="rowOpenORFold(true)">
              <el-icon><ArrowDown /></el-icon>
              <span>展开</span>
            </el-button>
          </el-tooltip>
          <el-tooltip content="折叠所有步骤" placement="top" :disabled="!isExpand">
            <el-button v-if="isExpand" class="action-button" @click="rowOpenORFold(false)">
              <el-icon><ArrowUp /></el-icon>
              <span>折叠</span>
            </el-button>
          </el-tooltip>
          <el-tooltip content="调试运行测试用例" placement="top">
            <el-button class="action-button" type="success" @click="runCase">
              <el-icon><VideoPlay /></el-icon>
              <span>调试</span>
            </el-button>
          </el-tooltip>
          <el-tooltip :content="this.case !== null ? '保存更改' : '创建新用例'" placement="top">
            <el-button 
              class="action-button save-button" 
              type="primary" 
              @click="this.case !== null ? editCaseSave() : addCaseSave()">
              <el-icon><Document /></el-icon>
              <span>保存</span>
            </el-button>
          </el-tooltip>
        </div>
      </div>
    </div>
    
    <el-row :gutter="10">
    <!-- 左边内容-->
    <el-col :span="6">
    <div class="tree-component">
      <el-form :model="editForm"  :rules="rulesCase" ref="CaseRef" label-width="80px" style="max-width: 500px">
      <el-form-item label="用例名称"  prop="name" size="mini">
        <el-input  v-model="editForm.name"  placeholder="请输入用例名称"/>
      </el-form-item>
      <el-form-item prop="project_id" label="所属项目" size="mini">
        <el-input v-model="editForm.project_id"   disabled />
      </el-form-item>
			<el-form-item label="用例描述" prop="desc">
        <el-input type="textarea" v-model="editForm.desc"   placeholder="请输入备注"/>
      </el-form-item>
      <el-form-item label="步骤总数：" label-width="93px"><div style="color: #00aaff;font-weight: bold;">{{editForm.stepCount}}</div></el-form-item>
		</el-form>
    </div>
    </el-col>
    <!-- 右边内容-->
    <el-col :span="18">
      <div class="stepStyle">
        <el-tag class="el-icon-plus" color="#61649f" style="margin-right: 10px;width: 100px" @click="showApiCite">HTTP请求</el-tag>
        <el-tag class="el-icon-plus" color="#E6A23C" style="margin-right: 10px;width: 100px" @click="AddController('if')">条件控制器</el-tag>
        <el-tag class="el-icon-plus" color="#02A7F0FF" style="margin-right: 10px;width: 100px" @click="AddController('for')">循环控制器</el-tag>
        <el-tag class="el-icon-plus" color="#7B4D12FF" style="margin-right: 10px;width: 100px" @click="AddController('script')">自定义脚本</el-tag>
        <el-tag class="el-icon-plus" color="#783887FF" style="margin-right: 10px;width: 100px" @click="AddController('sql')">SQL控制器</el-tag>
        <el-tag class="el-icon-plus" color="#67C23AFF" style="margin-right: 10px;width: 100px" @click="AddController('time')">等待控制器</el-tag>
      </div>
      <el-scrollbar height="calc(100vh - 190px)">
      <div style="margin-left: 20px; margin-right: 20px;">
      <el-tree
        :data="steps"
        :props="defaultProps"
        draggable
        :key="treeKey"
        :default-expand-all="isExpand"
        :expand-on-click-node="false"
        @node-click="handleStepClick"
        :allow-drop="allowDrop"
        @node-drop="updateStepOrder"
        @node-drag-start="handleDragStart"
        @node-drag-enter="handleDragEnter"
        @node-drag-leave="handleDragLeave"
        @node-drag-over="handleDragOver"
        @node-drag-end="handleDragEnd"
        class="custom-tree"
      >
    <template v-slot="{ node,data }">
      <el-card v-if="data.stepInfo" :class="['step-card', `step-card-${data.stepInfo.type}`]">
        <div slot="header" class="card-header">
         <el-row :gutter="10" type="flex" align="middle" justify="center">
          <el-col :span="18" class="card-main-content">
            <div class="card-content-wrapper">
              <!--api展示-->
              <div v-if="data.stepInfo.type==='api'" class="card-inner">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(97, 100, 159)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="#61649f">HTTP请求</el-tag>
                  <span class="method-tag">
                    <span v-if="data.stepInfo.method === 'POST'">
                      <b style="color: #49cc90;">{{ data.stepInfo.method }}</b>
                    </span>
                    <span v-if="data.stepInfo.method === 'GET'">
                      <b style="color: #61affe;">{{ data.stepInfo.method }}</b>
                    </span>
                    <span v-if="data.stepInfo.method === 'PUT'">
                      <b style="color: #fca130;">{{ data.stepInfo.method }}</b>
                    </span>
                    <span v-if="data.stepInfo.method === 'PATCH'">
                      <b style="color: #50e3c2;">{{ data.stepInfo.method }}</b>
                    </span>
                    <span v-if="data.stepInfo.method === 'DELETE'">
                      <b style="color: #f93e3e;">{{ data.stepInfo.method }}</b>
                    </span>
                    <span v-if="data.stepInfo.method === 'DEAD'">
                      <b style="color: rgb(201, 233, 104);">{{ data.stepInfo.method }}</b>
                    </span>
                  </span>
                </div>

                <div class="card-center">
                  <el-dropdown trigger="click" @click.stop>
                      <el-button type="text" v-if="Object.keys(data.stepInfo.host).length !== 0" @click.stop>{{data.stepInfo.host.name}}</el-button>
                      <el-button v-else type="text"  @click.stop>默认环境</el-button>
                    <template #dropdown>
                      <el-dropdown-menu>
                          <el-dropdown-item v-for="item in testEnvsWithDefault" :key="item.id" command='api' @click="envClick(item,data.stepInfo)">
                            {{item.name}}
                          </el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                  <b class="card-url">{{ data.stepInfo.url }}</b>
                  <span class="card-name">{{data.stepInfo.name }}</span>
                </div>
              </div>

              <!--if控制器展示-->
              <div v-if="data.stepInfo.type==='if'" class="card-inner">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(230, 162, 60)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="rgb(230, 162, 60)">条件控制器</el-tag>
                </div>
                <div class="card-center if-content">
                  <div class="if-controls-wrapper">
                    <el-input class="input-def" placeholder="变量，例如{{name}}" v-model="data.stepInfo.content.variable"/>
                    <el-select v-model="data.stepInfo.content.JudgmentMode" placeholder="请选择" style="width: 100px">
                      <el-option
                        v-for="item in options"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                    <el-input class="input-def" placeholder="值" v-model="data.stepInfo.content.value"/>
                    <el-input class="input-def" placeholder="备注" v-model="data.stepInfo.desc"/>
                  </div>
                </div>
              </div>

              <!--循环控制器展示-->
              <div v-if="data.stepInfo.type==='for'" class="card-inner" @click="toggleExpand(data.stepInfo)">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(2, 167, 240)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="rgb(2, 167, 240)">循环控制器</el-tag>
                </div>
                <div class="card-center">
                  <div class="for-controls-wrapper">
                    <el-radio-group v-model="data.stepInfo.content.select" @click.stop class="radio-group">
                      <el-radio label="count" value="count">次数循环</el-radio>
                      <el-radio label="for" value="for">for循环</el-radio>
                      <el-radio label="while" value="while" disabled>while循环</el-radio>
                    </el-radio-group>
                  </div>
                </div>
              </div>
              <div v-if="data.stepInfo.type==='for' && data.stepInfo.dlg" :key="data.id" @click.stop class="loop-details">
                <div v-if="data.stepInfo.content.select==='count' || data.stepInfo.content.select===''">
                  <div class="loop">
                    <div class="loop-control">
                      <span>循环次数</span>
                      <el-input v-model="data.stepInfo.content.cycleIndex" style="width: 200px" placeholder="循环次数" />
                    </div>
                    <div class="loop-control">
                      <span>循环间隔</span>
                      <el-input-number
                        v-model="data.stepInfo.content.cycleInterval"
                        :min="0"
                        :max="999"
                        controls-position="right"
                        placeholder="秒"
                      />
                      <span>秒</span>
                    </div>
                  </div>
                </div>
                <div v-if="data.stepInfo.content.select==='for'">
                  <div class="loop">
                    <div class="loop-control">
                      <el-input style="width: 200px" placeholder="定义变量名称" v-model="data.stepInfo.content.variableName"/>
                      <b>in</b>
                      <el-input style="width: 200px" placeholder="变量，例如{{name}}" v-model="data.stepInfo.content.variable"/>
                    </div>
                    <div class="loop-control">
                      <span>循环间隔</span>
                      <el-input-number
                        v-model="data.stepInfo.content.cycleInterval"
                        :min="0"
                        :max="999"
                        size="small"
                        controls-position="right"
                        placeholder="秒"
                      />
                      <span>秒</span>
                    </div>
                  </div>
                </div>
                <div v-if="data.stepInfo.content.select==='while'"><div class="loop">敬请期待！</div></div>
              </div>

              <!--自定义脚本展示-->
              <div v-if="data.stepInfo.type==='script'" class="card-inner">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(123, 77, 18)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="rgb(123, 77, 18)">自定义脚本</el-tag>
                </div>
                <div class="card-center">
                  <el-input v-if="data.stepInfo.inputDlg" v-model="data.stepInfo.name" @blur="cancelEditing(data.stepInfo)" ref="input" maxlength="50" @click.stop></el-input>
                  <el-button v-else class="script-button" plain type="text" @click="startEditing(data.stepInfo)" @click.stop>
                    {{data.stepInfo.name}}
                    <el-icon><Edit /></el-icon>
                  </el-button>
                </div>
              </div>
              <el-row :gutter="10" v-show="data.stepInfo.type==='script' && data.stepInfo.dlg" @click.stop class="script-editor">
                <el-col :span="18"><Editor v-model="data.stepInfo.script" lang="python" theme="chrome"></Editor></el-col>
                <el-col :span="6">
                  <el-divider>脚本模板</el-divider>
                  <div class="code_mod"><el-button type="success" size="mini" plain @click="addSetUptCodeMod(data.stepInfo,'func')">导入变量模块</el-button></div>
                  <div class="code_mod"><el-button type="success" size="mini" plain @click="addSetUptCodeMod(data.stepInfo,'ENV')">预设全局变量</el-button></div>
                  <div class="code_mod"><el-button type="success" size="mini" plain @click="addSetUptCodeMod(data.stepInfo,'env')">预设局部变量</el-button></div>
                  <div class="code_mod"><el-button type="success" size="mini" plain @click="addSetUptCodeMod(data.stepInfo,'sql')">执行sql查询</el-button></div>
                </el-col>
              </el-row>

              <!--sql控制器展示-->
              <div v-if="data.stepInfo.type==='sql'" class="card-inner">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(120, 56, 135)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="rgb(120, 56, 135)">SQL控制器</el-tag>
                </div>
                <div class="card-center">
                  <el-input v-if="data.stepInfo.inputDlg" v-model="data.stepInfo.name" @blur="cancelEditing(data.stepInfo)" ref="input" maxlength="50" @click.stop></el-input>
                  <el-button v-else class="script-button" plain type="text" @click="startEditing(data.stepInfo)" @click.stop>
                    {{data.stepInfo.name}}
                    <el-icon><Edit /></el-icon>
                  </el-button>
                </div>
              </div>
              <div v-show="data.stepInfo.type==='sql' && data.stepInfo.dlg" class="sql-message"><i>该功能敬请期待噢！</i></div>

              <!--time控制器展示-->
              <div v-if="data.stepInfo.type==='time'" class="card-inner">
                <div class="card-left">
                  <span class="step-icon" :style="{ color: 'rgb(103, 194, 58)' }">{{ getCardIndex(node.parent, node) }}</span>
                  <el-tag color="rgb(103, 194, 58)">等待控制器</el-tag>
                </div>
                <div class="card-center time-controller">
                  <div class="time-control">
                    <el-input-number
                      v-model="data.stepInfo.content.time"
                      :min="0"
                      :max="999"
                      size="small"
                      controls-position="right"
                      placeholder="秒"
                    />
                    <span>秒</span>
                  </div>
                </div>
              </div>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="card-actions">
              <el-switch
                v-model="data.status"
                inline-prompt
                size="default"
                @click="switchClick(data)"
                style="--el-switch-on-color: #53a8ff; --el-switch-off-color: #f56c6c"
              />
              <el-button size="default" icon="document" @click="copyTree(data)" circle class="action-button" />
              <el-button size="default" icon="delete" type="danger" @click="delTree(data)" circle class="action-button" />
            </div>
          </el-col>
         </el-row>
        </div>
      </el-card>
    </template>
      </el-tree>
      </div>
      </el-scrollbar>
    </el-col>
    </el-row >
    <apiCite v-if="addApiDlg" @childEvent="handleChildData" @close-modal="handleCloseModal"></apiCite>
  	<!-- 调试测试步骤窗口 -->
    <el-drawer v-model="editCaseDlg"   :with-header="false" size="50%"><newEditCase ref="childRef" @closeDrawer="handleClose"  :Interface_id="Interface_id" :copyDlg="copyDlg"  style="padding: 0 10px;"></newEditCase></el-drawer>
    <!-- 显示运行结果 -->
	  <el-drawer v-model="ResultDlg" :with-header="false" size="50%">
		<div style="padding:20px;">
			<el-descriptions title="执行结果" border :column="4" style="text-align: center;">
				<el-descriptions-item label="总数" ><b style="color: #00aaff">{{ runScentResult.all }}</b></el-descriptions-item>
				<el-descriptions-item label="通过"><b style="color: #00aa7f">{{ runScentResult.success }}</b></el-descriptions-item>
				<el-descriptions-item label="失败"><b style="color: orangered">{{ runScentResult.fail }}</b></el-descriptions-item>
				<el-descriptions-item label="错误"><b style="color: #fca130">{{ runScentResult.error }}</b></el-descriptions-item>
			</el-descriptions>
			<div style="height: 40px;line-height: 40px;"><b>执行详情</b></div>
			<el-scrollbar height="calc(100vh - 180px)">
				<el-table :data="runScentResult.cases" style="width: 100%" empty-text="暂无数据">
					<el-table-column type="expand">
						<template #default="props">
							<caseResult :result="props.row"></caseResult>
						</template>
					</el-table-column>
					<el-table-column label="步骤名" prop="name" />
					<el-table-column label="请求方法" prop="method">
            <template #default="props">
               <span v-if="props.row.type === 'api'">{{ props.row.method }}</span>
						</template>
          </el-table-column>
					<el-table-column label="响应状态码" prop="status_cede">
            <template #default="props">
               <span v-if="props.row.type === 'api'">{{ props.row.status_cede }}</span>
						</template>
          </el-table-column>
					<el-table-column label="执行结果" prop="state" min-width="40px">
						<template #default="props">
							<span v-if="props.row.state == '成功'" style="color: #00AA7F;">{{ props.row.state }}</span>
              <span v-else-if="props.row.state == '错误'" style="color: #F56C6C;">{{ props.row.state }}</span>
							<span v-else style="color:#fca130">{{ props.row.state }}</span>
						</template>
					</el-table-column>
				</el-table>
			</el-scrollbar>
		</div>
	</el-drawer>
  </div>
</template>

<script>
import {mapMutations, mapState} from "vuex";
import {ElMessage, ElNotification} from "element-plus";
import apiCite from '../../views/TestCase/apiCiteDlg.vue';
import newEditCase from '../../components/common/InterfaceNew/neweditCase.vue';
import caseResult from '../../components/common/caseResult.vue';
import Editor from'../../components/common/Editor.vue';
import { ref, reactive, toRefs, getCurrentInstance, onMounted, nextTick, watch } from 'vue'
import { ArrowDown, ArrowRight, Edit, Plus, Delete, DocumentAdd, Refresh, VideoPlay, Back, CaretRight, Document, View } from '@element-plus/icons-vue'
import { useRoute, useRouter } from 'vue-router'
export default {
  components:{
    apiCite,
    newEditCase,
    caseResult,
    Editor
  },
  data() {
    return{
      editForm:{
        name:'',
        project_id:'',
        desc:'',
        stepCount:0,
        creator:''
      },
      rulesCase: {
				name: [
					{
						required: true,
						message: '请输入用例名称',
						trigger: 'blur'
					}
				],
				project_id: [
					{
						required: true,
						message: '请选择项目',
						trigger: 'blur'
					}
				],
			},
      steps:[],
      addApiDlg:false,
      editCaseDlg: false,
      Interface_id: '',
      copyDlg: false,
      ResultDlg:false,
      runScentResult:'',
      ControllerData:{
        name: "",
        type: "",
        content: {},
        script:"",
        desc:"",
        creator:"",
      },
      options: [
          { value: 'equal', label: '等于' },
          { value: 'notEqual', label: '不等于' },
          { value: 'contains', label: '包含' },
          { value: 'notContains', label: '不包含' },
          { value: 'greaterThan', label: '大于' },
          { value: 'lessThan', label: '小于' },
          { value: 'greaterThanOrEqual', label: '大于等于' },
          { value: 'lessThanOrEqual', label: '小于等于' },
          { value: 'empty', label: '空' },
          { value: 'notEmpty', label: '非空' }
        ],
      test:'',
      treeKey: '',
      isExpand: false,
      }
    },

  computed: {
		...mapState(['pro','case','envId','testEnvs']),
    testEnvsWithDefault() {
      const withDefault = [...this.testEnvs];
      withDefault.unshift({ host:'默认环境host', name: '默认环境' });
      return withDefault;
    },
    username() {
			return window.sessionStorage.getItem('username');
		},
    defaultProps() {
      return {
        children: 'children',
        label: 'name',
      }
    },
	},
  watch: {
    steps: {
      deep: true
    }
  },
  methods: {
    ...mapMutations(['CaseInfo','clearCaseInfo']),
  getCardIndex(parent, node) {
    const index = parent.childNodes.indexOf(node);
    return index + 1;
  },

   async addCaseSave() {
    this.$refs.CaseRef.validate(async vaild => {
    // 判断是否验证通过，不通过则直接retrue
    if (!vaild) return;
    const params = {...this.editForm}
    params.creator = this.username
    params.project_id = this.pro.id
    const response = await this.$api.createTestCase(params);
      if (response.status === 201) {
        ElMessage({
          type: 'success',
          message: '保存成功',
          duration: 1000
        });
      }
    })},

   // 保存用例信息
   async editCaseSave() {
    this.$refs.CaseRef.validate(async vaild => {
    // 判断是否验证通过，不通过则直接retrue
    if (!vaild) return;
    const params = {...this.editForm}
    params.project_id = this.pro.id
    params.modifier = this.username;
    params.update_time = this.$tools.newTime()
    delete params.create_time
    delete params.creator
    delete params.project
    const response = await this.$api.updateTestCase(params.id, params);
        if (response.status === 200) {
          ElMessage({
            type: 'success',
            message: '保存成功',
            duration: 1000
          });
        this.editStepSave()
        }
    })
   },

  // 保存步骤信息
  async editStepSave() {
    const ControllerStepsData = this.steps
      .filter(step => step.stepInfo && step.stepInfo.type !== "api")
      .map(step => step);
    const response = await this.$api.updatesStepControll(ControllerStepsData)
      if (response.status === 201) {
        this.getCaseStep(this.case.id)
      }
  },

   reaiTime() {
      if (this.case) {
        this.editForm = this.case;
        this.editForm.project_id = this.pro.name;
      } else {
      this.editForm.project_id = this.pro.name;
      }
   },

   goBack() {
      if (this.case && this.case.back_type) {
      this.$router.push({ name: 'new-testplan' });
      this.clearCaseInfo();
      } else {
        this.$router.push({ name: 'TestCase' });
        this.clearCaseInfo()}
    },
   handleStepClick(data) {
      if (data.stepInfo.type==='api'){
      this.Interface_id = data.interfaceStep
      this.editCaseDlg = true
      this.$nextTick(() => {
        this.$refs.childRef.getInterfaceInfo(this.Interface_id);
          }
        )
      }
      else if(data.stepInfo.type==='script') {
           data.stepInfo.dlg = !data.stepInfo.dlg;
      }
      else if(data.stepInfo.type==='sql'){
        data.stepInfo.dlg = !data.stepInfo.dlg
      }
      else {}
    },
   handleClose() {
      this.addCaseDlg = false;
      this.editCaseDlg = false;
    },
    getRowClassName(row) {
      switch (row) {
        case 'api':
          return '--el-card-border-color:rgb(97, 100, 159);'
        case 'if':
          return '--el-card-border-color:rgb(230, 162, 60);'
        case 'for':
          return '--el-card-border-color:rgb(2, 167, 240);'
        case 'script':
          return '--el-card-border-color:rgb(123, 77, 18);'
        case 'time':
          return '--el-card-border-color:rgb(103, 194, 58);'
        case 'sql':
          return '--el-card-border-color:rgb(120, 56, 135);'
        default:
          return '';
    }
  },
   allowDrop(draggingNode, dropNode,type) {
      // 只有 type 为 api, for, if 的节点可以作为父级节点
      const allowedParentTypes = ['for', 'if'];
      if (!allowedParentTypes.includes(dropNode.data.stepInfo.type)) {
        return type === "prev" || type === "next";

      }else {
        return true
      };
  },
async copyTree(data, parentId = null, isLastCall = true) {
  event.stopPropagation();
  let order_s = this.steps.length > 0 ? this.steps.length + 1 : 1;

  // if (data.parent_id) {
  //       parentId = data.parent_id;
  //   }
  if (data.stepInfo.type === 'api') {
    await this.$api.createTestCaseStep({ case: this.case.id, interfaceStep: data.interfaceStep, sort: order_s, parent_id: parentId });
  } else {
    data.stepInfo.case = this.case.id;
    data.stepInfo.sort = order_s;
    data.stepInfo.parent_id = parentId;
    const Controllerresponse = await this.$api.copyStepControll(data.stepInfo);
    const setpId = Controllerresponse.data.setpId;
    // 递归复制子节点
    if (data.children) {
      let childCalls = data.children.map((child, index) => {
        const isLast = isLastCall && index === data.children.length - 1; // 是否为最后一次调用
        return this.copyTree(child, setpId, isLast); // 递归调用 copyTree 函数
      });
      await Promise.all(childCalls); // 等待所有子节点的递归调用完成
    }
  }

  // 所有递归调用完成后再刷新页面
  if (isLastCall) {
    this.getCaseStep(this.case.id);
  }
},

  async delTree(data) {
    event.stopPropagation();
    if (data.stepInfo.type==='api'){
          const response = await this.$api.delTestCaseStep(data.id);
			if (response.status === 204) {
			    this.getCaseStep(this.case.id)
			}
    }
    else {
      const response = await this.$api.delTestCaseStep(data.id);
			if (response.status === 204) {
			  const res = await this.$api.delStepControll(data.controllerStep);
			  if (res.status === 204){
			    this.getCaseStep(this.case.id)
          }
			}}
  },
  showApiCite() {
   this.$refs.CaseRef.validate(async vaild => {
    // 判断是否验证通过，不通过则直接return
    if (!vaild) return;
    this.addApiDlg = true;})
  },
  handleCloseModal() {
      this.addApiDlg = false; // 关闭弹窗
    },
  async handleChildData(data) {
    let order_s = this.steps.length > 0 ? this.steps.length + 1 : 1;
    let newDataArray = [];
    data.forEach(item => {
      // 遍历data数组中的每个元素，为每个元素创建一个新的对象，其中包含 sort、case 和 interfaceStep 字段
      let newItem = {
        sort: order_s,
        case: this.case.id,
        interfaceStep: item
      };
      newDataArray.push(newItem); // 将新创建的对象添加到新数组中
      order_s++;
    });
    const response = await this.$api.createsTestCaseStep(newDataArray)
      if (response.status === 201) {
          this.getCaseStep(this.case.id)
      }
  },
  async getCaseStep(cases) {
    const response = await this.$api.getTestCaseStep(cases)
        if (response.status === 200) {
        this.steps = response.data;
        this.editForm.stepCount = this.countSteps(this.steps);
        this.rowOpenORFold(true)
        }
  },
  // 递归函数来统计步骤总数
  countSteps(steps) {
      let count = 0;
      steps.forEach(step => {
          count += 1; // 计算当前步骤
          if (step.children && step.children.length > 0) {
              count += this.countSteps(step.children); // 递归计算子步骤
          }
      });
      return count;
  },

  async switchClick() {
    event.stopPropagation();
    this.updateStepOrder()
  },

  handleItemClick(item, data, event) {
    // 阻止事件冒泡
    if (event) {
      event.stopPropagation();
      event.preventDefault();
    }
    
    // 添加详细日志
    console.log('handleItemClick 被调用:', { 
      item: item, 
      data: data,
      itemName: item ? item.name : null,
      dataType: data ? data.type : null,
      dataId: data ? data.id : null
    });
    
    // 调用环境点击处理函数
    this.envClick(item, data);
  },
  
  async updateStepOrder() {
    const setParentIds = (node, parentId, parentSort) => {
    // 设置父节点的排序字段
    node.sort = parentSort;
    // 如果节点有子节点，则递归设置子节点的 parent_id 和排序字段
    if (node.children && node.children.length > 0) {
        node.children.forEach((child, childIndex) => {
            // 设置子节点的 parent_id 为当前节点的 id
            child.parent_id = node.id;
            // 设置子节点的排序字段
            child.sort = childIndex + 1;
            // 递归调用，处理子节点的子节点
            setParentIds(child, node.id, child.sort);
          });
        }
    };
    // 遍历步骤数组，设置父节点的排序字段和子节点的 parent_id 和排序字段
    this.steps.forEach((parent, parentIndex) => {
        // 设置父节点的排序字段
        parent.sort = parentIndex + 1;
        // 如果父节点有子节点，则设置子节点的 parent_id 和排序字段
        if (parent.children && parent.children.length > 0) {
            // 调用函数设置父节点和子节点的属性
            setParentIds(parent, parent.id, parent.sort);
        }
    });
			// 发送请求后端修改用例顺序
			const response = await this.$api.updateCaseStepOrder(this.steps);
			if (response.status === 200) {
          ElNotification({
              duration: 500,
              title: '调整成功',
              type: 'success',
            })
			}
		},

  // 运行测试用例
  async runCase() {
			if (this.envId) {
				const params = {
					env: this.envId,
					scene: this.case.id
				};
          ElNotification({
            title: '开始运行',
            message: '运行过程中请稍等片刻噢',
            type: 'success',
            duration:1000
          });
				const response = await this.$api.runCases(this.case.id, params);
				if (response.status == 200) {
					// 显示执行结果到窗口页面
					this.runScentResult = response.data;
					this.ResultDlg = true;
				}
			} else {
				this.$message({
					type: 'warning',
					message: '当前未选中执行环境!',
					duration: 1000
				});
			}
		},

  toggleExpand(data) {
    data.dlg = ! data.dlg;
  },

  startEditing(data) {
    if(data.type==='script'){data.inputDlg = true}else {data.inputDlg = true}
    this.$nextTick(() => {
      this.$refs.input.focus();
    });
  },
  cancelEditing(data) {
    data.inputDlg = false;
  },
  addSetUptCodeMod(data,tp) {
			switch (tp) {
				case 'ENV':
					data.script += '\n# 设置全局变量 \nBaseTest().save_global_variable("变量名","变量值")';
					break;
				case 'env':
					data.script += '\n# 设置局部变量  \nBaseTest().save_env_variable("变量名","变量值")';
					break;
				case 'func':
					data.script += '\nfrom apitestengine.core.cases import BaseTest';
					break;
				case 'sql':
					data.script +=
						'\n# ----执行sql语句(需要在环境中配置数据库连接信息)----\n# db.连接名.execute_all(sql语句) \nsql = "SELECT count(*) as count FROM futureloan.member"\nres = db.aliyun.execute_all(sql)';
					break;
			}
		},
  // 添加拖拽事件处理
  handleDragStart(node, ev) {
    console.log('drag start', node);
    // 强制创建拖拽指示器
    this.$nextTick(() => {
      const indicator = document.querySelector('.el-tree-node__drop-indicator');
      if (indicator) {
        indicator.style.display = 'block';
        indicator.style.visibility = 'visible';
        indicator.style.opacity = '1';
      }
    });
    
    // 添加滚动屏幕功能
    document.addEventListener('mousemove', function(event) {
      const mouseY = event.clientY;
      const treeElement = document.querySelector('.el-tree');
      const elementTop = treeElement ? treeElement.getBoundingClientRect().top : 0;

      if (mouseY < 100 && elementTop > 0) {
        window.scrollBy(0, -10);
      } else if (mouseY > window.innerHeight - 100) {
        window.scrollBy(0, 10);
      }
    });
  },
  
  handleDragEnter(draggingNode, dropNode, ev) {
    console.log('tree drag enter:', dropNode.label);
  },
  
  handleDragLeave(draggingNode, dropNode, ev) {
    console.log('tree drag leave:', dropNode.label);
  },
  
  handleDragOver(draggingNode, dropNode, ev) {
    console.log('tree drag over:', dropNode.label);
  },
  
  handleDragEnd(draggingNode, dropNode, dropType, ev) {
    console.log('tree drag end:', dropNode && dropNode.label, dropType);
  },

  // 添加条件控制器
  async AddController(types) {
    let order_s = this.steps.length > 0 ? this.steps.length + 1 : 1;
    if(types ==='if'){
      this.ControllerData = {
        name: "条件控制器",
        type: "if",
        content: {
          variable:"",
          JudgmentMode:"",
          value:"",
        },
        script:"",
        desc:"",
        creator:this.username,
      }
    }
    else if(types ==='for'){
        this.ControllerData = {
          name: "循环控制器",
          type: "for",
          content: {
            select:"count",
            cycleIndex:"",
            cycleInterval:"",
            variable:"",
            variableName:""
          },
          script:"",
          desc:"",
          creator:this.username,
      }

    }
    else if(types ==='script'){
      this.ControllerData = {
        name: "自定义脚本",
        type: "script",
        content: {},
        script:"",
        desc:"",
        creator:this.username,
      }
    }
    else if(types ==='time'){
      this.ControllerData = {
        name: "定时控制器",
        type: "time",
        content: {
          time:""
        },
        script:"",
        desc:"",
        creator:this.username,
      }
    }
    else if(types ==='sql'){
      this.ControllerData = {
        name: "数据库操作",
        type: "sql",
        content: {},
        script:"",
        desc:"",
        creator:this.username,
      }
    }else {
      throw new Error('types is not defined');
    }
    const Controllerresponse = await this.$api.createStepControll(this.ControllerData)
      if (Controllerresponse.status === 201) {
            const response = await this.$api.createTestCaseStep({ case: this.case.id, controllerStep:Controllerresponse.data.id, sort: order_s })
              if (response.status === 201) {
                this.getCaseStep(this.case.id)
              }
          }
    },

  rowOpenORFold(isExpand) {
	      this.treeKey = +new Date()
	      this.isExpand = isExpand
	    },
   async envClick(item,data){
      let params;
      if(item.name==='默认环境'){
        params = {host:{}}
      }else {
        params = {host:{host:item.host,name:item.name}}
      }
      const response = await this.$api.updatenewInterface( data.id, params);
      if (response.status === 200) {
          ElMessage({
            type: 'success',
            message: '变更成功',
            duration: 1000
          });
          }
      this.getCaseStep(this.case.id)
    },

  },
  created() {
    this.reaiTime();
    if (this.case && this.case.id) {
       this.getCaseStep(this.case.id)
    }
  },
  
  mounted() {
    // 添加全局样式确保拖拽提示线显示
    const style = document.createElement('style');
    style.innerHTML = `
      .el-tree-node__drop-indicator {
        position: absolute !important;
        left: 0 !important;
        right: 0 !important;
        height: 5px !important;
        background-color: #2b85e4 !important;
        z-index: 100000 !important;
        pointer-events: none !important;
        border-radius: 2px !important;
        box-shadow: 0 0 6px rgba(43, 133, 228, 0.8) !important;
        display: block !important;
        visibility: visible !important;
        opacity: 1 !important;
      }
    `;
    document.head.appendChild(style);
  }

}
</script>

<style scoped>
.el-dropdown-menu__item {
  color: #606266;
  cursor: pointer !important;
  z-index: 9999;
  &:hover {
    background-color: #ebf5ff;
  }
}

.el-dropdown {
  z-index: 800;
}
.el-tree {
    --el-tree-node-hover-background-color: #ecf5ff;
    margin-right: 50px;
    position: relative;
    overflow: visible !important;
}
.tree-component {
  height: 100vh;
  margin-left: 15px;
  padding-right: 10px;
  padding-top: 15px;
  box-shadow: 5px 0 5px rgba(0, 0, 0, 0.06);
}

/* 确保树节点允许溢出内容显示，以支持下拉菜单 */
:deep(.el-tree-node__content) {
    padding: 4px 4px 4px 0px;
    height: auto;
    overflow: visible !important;
}

/* 卡片通用样式 */
.step-card {
  border-radius: 10px;
  margin-bottom: 8px;
  transition: all 0.3s;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  width: 100%; 
  position: relative;
  z-index: 5;
  overflow: visible !important;
}

/* 不同类型卡片的边框颜色 */
.step-card-api {
  border-left: 4px solid #61649f;
}
.step-card-if {
  border-left: 4px solid rgb(230, 162, 60);
}
.step-card-for {
  border-left: 4px solid rgb(2, 167, 240);
}
.step-card-script {
  border-left: 4px solid rgb(123, 77, 18);
}
.step-card-sql {
  border-left: 4px solid rgb(120, 56, 135);
}
.step-card-time {
  border-left: 4px solid rgb(103, 194, 58);
}

.card-header {
  padding: 12px;
  width: 100%;
}

.card-content-wrapper {
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow: visible; /* 修改为visible，允许下拉菜单显示在容器外 */
  max-width: 100%; /* 确保不超出父容器 */
}

.card-inner {
  display: flex;
  align-items: center;
  justify-content: flex-start; /* 从左开始 */
  width: 100%;
  padding: 0 20px; /* 增加左右内边距从15px到20px */
  min-height: 40px; /* 确保最小高度 */
  position: relative; /* 添加相对定位 */
  overflow: visible; /* 确保下拉菜单可见 */
}

.card-left {
  display: flex;
  align-items: center;
  width: 180px; /* 进一步增加宽度 */
  min-width: 180px; /* 确保最小宽度也相应增加 */
  justify-content: flex-start; /* 左对齐 */
  flex-shrink: 0; /* 防止被压缩 */
  margin-right: 15px; /* 增加右边距 */
  gap: 10px; /* 使用gap属性控制子元素间距 */
}

.card-center {
  margin-left: 10px; /* 减少左边距从50px到10px */
  flex-grow: 1;
  overflow: hidden;
}

.card-actions {
  display: flex;
  align-items: center;
  justify-content: center; /* 居中对齐操作按钮 */
  gap: 8px; /* 按钮之间增加间距 */
}

.action-button {
  margin-left: 0; /* 删除左边距，使用gap控制间距 */
  transition: all 0.2s;
}

.action-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.method-tag {
  min-width: 60px;
  margin-left: 0; /* 移除左边距，依靠父元素的gap来控制间距 */
  font-size: 15px;
  flex-shrink: 0; /* 防止被压缩 */
}

.card-url {
  font-size: 15px;
  margin: 0 10px;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60%; /* 防止URL过长 */
}

.card-name {
  font-size: 14px;
  color: #888;
  margin-left: 5px;
}

.el-tag {
  color: #ffffff;
  width: 80px;
  height: 30px;
  text-align: center;
  font-size: 13px;
  line-height: 30px;
  margin-right: 0; /* 移除右边距，使用上面的gap代替 */
  margin-left: 0; /* 移除左边距，使用上面的gap代替 */
  flex-shrink: 0; /* 防止标签被压缩 */
}

.step-icon {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 24px;
  height: 24px;
  margin-right: 0; /* 移除右边距，使用上面的gap代替 */
  font-weight: bold;
  border-radius: 50%;
  text-align: center;
  background-color: white;
  border: 2px solid currentColor;
  font-size: 14px;
  line-height: 24px;
  box-sizing: border-box;
  flex-shrink: 0; /* 防止图标被压缩 */
}

.input-def {
  width: 160px;
  margin-right: 0; /* 移除右边距 */
  margin-bottom: 0; /* 移除底部边距 */
  flex-shrink: 0; /* 防止输入框被压缩 */
}

.if-content {
  flex-wrap: nowrap;
  gap: 8px;
  justify-content: flex-start; /* 左对齐内容 */
  width: 100%;
  padding: 8px 0;
  overflow: visible; /* 修改为visible，允许下拉菜单显示 */
  position: relative; /* 添加相对定位 */
}

.if-controls-wrapper {
  display: flex;
  flex-wrap: wrap; /* 允许在小屏幕上换行 */
  align-items: center;
  width: 100%;
  gap: 8px;
  position: relative; /* 添加相对定位 */
  overflow: visible !important; /* 确保下拉菜单可见 */
  min-width: min-content; /* 确保内容不会被压缩 */
  z-index: 20; /* 增加层级 */
}

.radio-group {
  display: flex;
  flex-wrap: nowrap;
  gap: 20px;
  white-space: nowrap;
}

.for-controls-wrapper {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  position: relative;
  overflow: visible;
}

.loop {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap; /* 允许换行 */
  gap: 20px;
  margin: 15px 0;
  width: 100%;
  overflow: visible;
  position: relative;
}

.loop-control {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  flex-shrink: 0;
}

.loop-details {
  background-color: #f9f9f9;
  border-radius: 0 0 8px 8px;
  padding: 10px 15px;
  margin-top: 5px;
  width: 100%;
  overflow: visible;
  position: relative;
}

.script-button {
  color: #333;
  border: none;
  outline: none;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: auto;
  margin: 0; /* 移除边距 */
  padding: 0 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.script-button .el-icon {
  margin-left: 5px;
  font-size: 14px;
}

.code_mod {
  margin-bottom: 8px;
  text-align: center;
}

.code_mod .el-button {
  margin: 0 auto;
  display: block;
  width: 100%;
}

.script-editor {
  padding: 10px 0;
  border-top: 1px dashed #eee;
  margin-top: 10px;
  width: 100%;
  position: relative;
  z-index: 1;
}

.sql-message {
  text-align: center;
  color: #666;
  padding: 15px 0;
  font-style: italic;
  width: 100%;
  position: relative;
}

.time-controller {
  display: flex;
  align-items: center;
  justify-content: flex-start; /* 左对齐 */
  width: 100%;
  flex-wrap: nowrap;
}

.time-control {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

/* 确保树组件中的内容宽度统一 */
:deep(.el-tree-node__content) {
  padding: 4px 4px 4px 0px;
  height: auto;
  width: 100%;
  background: #f9f9f9;
}

.card-main-content {
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  width: 100%;
}

/* 顶部操作按钮样式统一 */
.stepStyle {
  margin-left: 45px;
  margin-bottom: 10px;
  cursor: pointer;
}

/* 现代化头部样式 */
.page-header-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  background: #fff;
  border-radius: 8px;
  margin-bottom: 16px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  position: relative;
  overflow: hidden;
}

.page-header-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 4px;
  background: linear-gradient(to bottom, #409eff, #2585ff);
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.header-left {
  display: flex;
  align-items: center;
}

.back-button {
  display: flex;
  align-items: center;
  font-size: 14px;
  border: none;
  background: transparent;
  color: #606266;
  transition: all 0.3s;
  padding: 8px 12px;
  border-radius: 4px;
}

.back-button:hover {
  color: #409eff;
  transform: translateX(-2px);
  background-color: rgba(64, 158, 255, 0.1);
}

.page-title {
  margin-left: 16px;
  font-weight: 600;
  font-size: 16px;
  color: #303133;
  border-left: 4px solid #409eff;
  padding-left: 16px;
}

.header-actions {
  display: flex;
  align-items: center;
}

.header-actions .action-button {
  margin-left: 10px;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  height: 36px;
}

.header-actions .action-button:first-child {
  margin-left: 0;
}

.header-actions .action-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.save-button {
  font-weight: 500;
  min-width: 86px;
}

.page-container {
  background-color: #f5f7fa;
  min-height: 100vh;
  padding: 16px;
}

:deep(.el-tree) {
  overflow: visible !important;
}

:deep(.el-scrollbar__wrap) {
  overflow-x: auto !important;
  overflow-y: auto !important;
}

:deep(.el-scrollbar__view) {
  overflow: visible;
}

:deep(.judgment-popper) {
  z-index: 9999 !important;
  position: absolute !important; /* 改为绝对定位 */
  transform-origin: center top !important;
}

:deep(.el-popper), 
:deep(.el-dropdown-menu) {
  z-index: 99999 !important;
}

:deep(.el-dropdown-menu .el-dropdown-menu__item) {
  cursor: pointer !important;
}

/* 优化所有控制器元素的z-index */
.el-dropdown,
.el-radio-group {
  z-index: 5;
}

/* 确保el-tree和卡片显示正常 */
:deep(.el-tree-node) {
  overflow: visible;
}

:deep(.el-card) {
  overflow: visible;
  --el-card-padding:0;
}
.card-header[data-v-731abb76] {
    padding: 6px;
    width: 100%;
}
:deep(.el-card__body) {
  overflow: visible;
}

/* 进一步增强下拉菜单的显示 */
:deep(.el-dropdown__popper) {
  position: absolute !important; /* 改为绝对定位 */
  z-index: 99999 !important;
}

.env-dropdown-item {
  padding: 8px 20px;
  cursor: pointer !important;
  display: block;
  width: 100%;
  text-align: left;
}

/* 修复HTTP请求环境选择的样式 */
.custom-dropdown-item {
  padding: 10px 20px;
  cursor: pointer !important;
  display: block;
  width: 100%;
  text-align: left;
  color: #606266;
  line-height: 1.5;
  box-sizing: border-box;
  white-space: nowrap;
  z-index: 999999 !important;
  position: relative;
  transition: all 0.2s;
}

.custom-dropdown-item:hover {
  background-color: #ecf5ff;
  color: #409eff;
}

.custom-dropdown-item:active {
  background-color: #d9ecff;
  color: #409eff;
}

/* 自定义树组件样式 */
.custom-tree {
  overflow: visible !important;
  position: relative;
  z-index: 1;
}

/* 添加媒体查询，针对小屏幕进行优化 */
@media (max-width: 1200px) {
  .card-inner {
    flex-wrap: wrap;
    padding: 10px;
  }
  
  .card-left {
    width: auto;
    min-width: 150px;
    margin-right: 10px;
  }
  
  .if-controls-wrapper {
    flex-wrap: wrap;
  }
  
  .loop-control {
    margin-bottom: 10px;
  }
  
  .card-actions {
    justify-content: flex-end;
  }
  
  .card-center {
    width: 100%;
    margin-top: 10px;
    margin-left: 0;
  }

  .card-url {
    max-width: 100%;
    margin: 5px 0;
  }
  
  .input-def {
    width: 100%;
    margin-bottom: 8px;
  }
  
  .el-tag {
    width: auto;
    padding: 0 8px;
  }
  
  /* HTTP请求专用样式 */
  .step-card-api .card-center {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }
  
  .step-card-api .card-url {
    max-width: 100%;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    order: 2;
  }
  
  .step-card-api .el-dropdown {
    margin-bottom: 5px;
    order: 1;
  }
  
  .step-card-api .card-name {
    order: 3;
    margin-top: 5px;
  }
  
  /* 条件控制器专用样式 */
  .step-card-if .if-controls-wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  
  .step-card-if .if-controls-wrapper .el-input:last-child {
    grid-column: span 2;
  }
  
  /* 循环控制器专用样式 */
  .step-card-for .for-controls-wrapper {
    width: 100%;
  }
  
  .step-card-for .loop {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .step-card-for .loop-control {
    width: 100%;
    margin-bottom: 8px;
  }
}

@media (max-width: 768px) {
  .card-main-content {
    width: 100%;
  }
  
  .card-actions {
    width: 100%;
    justify-content: center;
    margin-top: 10px;
  }
  
  :deep(.el-row) {
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  
  .header-actions {
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-end;
  }
  
  .header-actions .action-button {
    margin-left: 5px;
  }
  
  /* 减小间距和调整布局 */
  .card-inner {
    padding: 5px 10px;
  }
  
  .el-card {
    margin-bottom: 5px;
  }
  
  .card-left {
    min-width: 130px;
    gap: 5px;
  }
  
  .step-icon {
    width: 20px;
    height: 20px;
    font-size: 12px;
    line-height: 20px;
  }
  
  .el-tag {
    font-size: 12px;
    height: 25px;
    line-height: 25px;
  }
  
  /* 修复脚本编辑器在小屏幕上的显示 */
  .script-editor {
    display: flex;
    flex-direction: column;
  }
  
  :deep(.script-editor .el-col) {
    width: 100% !important;
    margin-bottom: 10px;
  }
}

/* 确保步骤卡片相对于树的位置 */
.step-card {
  border-radius: 10px;
  margin-bottom: 8px;
  transition: all 0.3s;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  width: 100%; 
  position: relative;
  z-index: 5;
  overflow: visible !important;
}

/* 添加el-tree拖拽提示线样式 */
:deep(.el-tree-node__drop-indicator) {
  position: absolute;
  left: 0;
  right: 0;
  height: 4px !important; /* 增加高度使其更明显 */
  background-color: #2b85e4 !important; /* 更鲜明的蓝色 */
  z-index: 99999 !important; /* 确保最高层级 */
  pointer-events: none;
  border-radius: 2px;
  box-shadow: 0 0 6px rgba(43, 133, 228, 0.8); /* 添加阴影效果使线更明显 */
}

/* 加强拖拽提示线可见性 */
:deep(.el-tree-node.is-drop-inner > .el-tree-node__content) {
  background-color: rgba(43, 133, 228, 0.2) !important;
  border: 1px dashed #2b85e4 !important; /* 添加边框 */
}

/* 鼠标拖拽样式 */
:deep(.el-tree-node.is-dragging) {
  opacity: 0.7;
  background-color: #f0f9ff !important;
  border: 1px dashed #2b85e4 !important;
}

:deep(.el-tree-node.is-dragging-over) {
  background-color: #e6f1fc !important;
}

/* 确保drop-indicator不被遮挡 */
:deep(.el-tree) {
  position: relative; /* 确保相对定位 */
}

:deep(.el-tree-node) {
  position: relative; /* 确保相对定位 */
}

/* 全局覆盖el-tree-node__drop-indicator样式，防止被其他样式覆盖 */
body .el-tree-node__drop-indicator {
  position: absolute;
  left: 0;
  right: 0;
  height: 4px !important;
  background-color: #2b85e4 !important;
  z-index: 99999 !important;
  pointer-events: none;
  border-radius: 2px;
  box-shadow: 0 0 6px rgba(43, 133, 228, 0.8);
}
</style>